﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace WebCache
{
    public abstract class BaseCache:ICache
    {

        #region ICache Members

        public abstract string[] Keys
        {
            get;
        }

        public abstract object this[string key]
        {
            get;
            set;
        }

        public bool Exist(string key)
        {
            return this[key] == null;
        }

        public T Get<T>(string key)
        {
            return (T)this[key];
        }

        public bool TryGet<T>(string key, out T t)
        {
            if (Exist(key))
            {
                t = Get<T>(key);
                return true;
            }
            else
            {
                t = default(T);
                return false;
            }
        }

        public void Add<T>(string key, T t)
        {
            this[key] = t;
        }

        public void Add<T>(string key, T t, Func<T> updator)
        {
            Add(key, t);
            if (updator != null) Add(key + "_updator", updator);
        }

        public void SetUpdator<T>(string key, Func<T> updator)
        {
            if (updator != null) Add(key + "_updator", updator);
        }

        private void Refresh<T>(string key, bool checkExists)
        {
            Func<T> updator = null;
            if (checkExists && TryGet<Func<T>>(key, out updator)) this[key] = updator();
            else if (!checkExists) this[key] = Get<Func<T>>(key)();
        }

        public void Refresh<T>(string key)
        {
            Refresh<T>(key, true);
        }

        public void RefreshAll()
        {
            foreach (string key in Keys) Refresh<object>(key,false);
        }

        public abstract void Remove(string key);

        public void Clear()
        {
            foreach (string key in Keys) Remove(key);
        }

        #endregion
    }
}
